package com.kobeliu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.kobeliu.api.feign.UsersMicroServiceFeign;
import com.kobeliu.base.BaseInfoProperties;
import com.kobeliu.enums.AggsUserType;
import com.kobeliu.enums.CompanyReviewStatus;
import com.kobeliu.enums.YesOrNo;
import com.kobeliu.exceptions.GraceException;
import com.kobeliu.mapper.CompanyMapper;
import com.kobeliu.mapper.CompanyMapperCustom;
import com.kobeliu.pojo.Company;
import com.kobeliu.pojo.bo.CreateCompanyBO;
import com.kobeliu.pojo.bo.ModifyCompanyInfoBO;
import com.kobeliu.pojo.bo.QueryCompanyBO;
import com.kobeliu.pojo.bo.ReviewCompanyBO;
import com.kobeliu.pojo.eo.AggsUserEO;
import com.kobeliu.pojo.vo.CompanyInfoVO;
import com.kobeliu.pojo.vo.CompanySimpleVO;
import com.kobeliu.result.GraceJSONResult;
import com.kobeliu.result.ResponseStatusEnum;
import com.kobeliu.service.CompanyService;
import com.kobeliu.utils.LocalDateUtils;
import com.kobeliu.utils.PagedGridResult;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.crypto.fpe.FPEEngine;
import org.checkerframework.checker.units.qual.A;
import org.checkerframework.checker.units.qual.C;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class CompanyServiceImpl extends BaseInfoProperties implements CompanyService {


    @Autowired
    private CompanyMapper companyMapper;

    @Autowired
    private UsersMicroServiceFeign usersMicroServiceFeign;

    @Autowired
    private ElasticsearchRestTemplate esTemplate;

    @Autowired
    private CompanyMapperCustom companyMapperCustom;


    @Override
    public Company getByFullName(String fullName) {
        return companyMapper.selectOne(new QueryWrapper<Company>().eq("company_name",fullName));
    }

    @Transactional
    @Override
    public String createNewCompany(CreateCompanyBO bo) {

        Company company = new Company();
        BeanUtils.copyProperties(bo,company);

        //填入初始化内容
        company.setIsVip(YesOrNo.NO.type);
        company.setReviewStatus(CompanyReviewStatus.NOTHING.type);
        company.setCreatedTime(LocalDateTime.now());
        company.setUpdatedTime(LocalDateTime.now());

        if(bo.getCompanyId()!=null){
            company.setId(bo.getCompanyId());
            companyMapper.updateById(company);
        }else{
            companyMapper.insert(company);
        }

        return company.getId();
    }

    @Transactional
    @Override
    public String resetNewCompany(CreateCompanyBO bo) {

        Company company = new Company();
        BeanUtils.copyProperties(bo,company);

        company.setId(bo.getCompanyId());
        //驳回状态 --》 待审核
        company.setReviewStatus(CompanyReviewStatus.NOTHING.type);
        company.setUpdatedTime(LocalDateTime.now());

        companyMapper.updateById(company);

        return bo.getCompanyId();
    }

    @Override
    public Company getByCompanyId(String companyId) {
        return companyMapper.selectById(companyId);
    }

    @Override
    public Long getCountByCompanyId(String companyId) {
        return usersMicroServiceFeign.getCountByCompanyId(companyId);
    }

    @Transactional
    @Override
    public void commitReviewCompanyInfo(ReviewCompanyBO companyBO) {
        Company pendingCompany = new Company();
        pendingCompany.setId(companyBO.getCompanyId());
        pendingCompany.setReviewStatus(CompanyReviewStatus.REVIEW_ING.type);
        pendingCompany.setReviewReplay(""); //如果有内容，则充值覆盖之前的审核意见
        pendingCompany.setAuthLetter(companyBO.getAuthLetter());

        pendingCompany.setCommitUserId(companyBO.getHrUserId());
        pendingCompany.setCommitUserMobile(companyBO.getHrMobile());
        pendingCompany.setCommitDate(LocalDate.now());

        pendingCompany.setUpdatedTime(LocalDateTime.now());

        companyMapper.updateById(pendingCompany);
    }

    @Override
    public PagedGridResult queryCompanyListPaged(QueryCompanyBO bo, Integer page, Integer limit) {

        PageHelper.startPage(page,limit);

        //查询中有一个user，company表中没有需要连表查询
        Map<String,Object> map = new HashMap<>();

        map.put("companyName",bo.getCompanyName());
        map.put("realName",bo.getCommitUser());
        map.put("reviewStatus",bo.getReviewStatus());
        map.put("commitDateStart",bo.getCommitDateStart());
        map.put("commitDateENd",bo.getCommitDateEnd());

        List<CompanyInfoVO> companyInfoVOS = companyMapperCustom.queryCompanyList(map);

        return setterPagedGrid(companyInfoVOS,page);
    }

    @Override
    public CompanyInfoVO getCompanyInfoVO(String companyId) {
        Map<String,Object> map = new HashMap<>();
        map.put("companyId",companyId);
        return companyMapperCustom.getCompanyInfo(map);
    }

    @Transactional
    @Override
    public void updateReviewInfo(ReviewCompanyBO bo) {

        Company pending = new Company();
        BeanUtils.copyProperties(bo,pending);

        pending.setId(bo.getCompanyId());
        pending.setReviewStatus(bo.getReviewStatus());
        pending.setReviewReplay(bo.getReviewReplay());
        pending.setUpdatedTime(LocalDateTime.now());

        companyMapper.updateById(pending);
    }

    @Transactional
    @Override
    public void updateCompanyInfo(ModifyCompanyInfoBO infoBO) {

        String companyId = infoBO.getCompanyId();
        if(StringUtils.isBlank(companyId))
            GraceException.display(ResponseStatusEnum.COMPANY_INFO_UPDATED_ERROR);

        Company pending = new Company();
        pending.setId(infoBO.getCompanyId());
        pending.setUpdatedTime(LocalDateTime.now());

        BeanUtils.copyProperties(infoBO,pending);

        companyMapper.updateById(pending);

        //之后删除相关的redis canal进行控制就不需要操作redis了
        redis.del(REDIS_COMPANY_MORE_INFO+":"+infoBO.getCompanyId());
        redis.del(REDIS_COMPANY_BASE_INFO+":"+infoBO.getCompanyId());

    }

    @Override
    public List<CompanyInfoVO> getList(List<String> companyIds) {

        List<CompanyInfoVO> companyInfos = new ArrayList<>();
        if(companyIds.size()==0){
            return companyInfos;
        }

        String[] ids = new String[companyIds.size()];

        for (int i = 0; i < companyIds.size(); i++) {
            ids[i] = companyIds.get(i);
        }

        List<Company> companies = companyMapper.selectList(
                new QueryWrapper<Company>()
                .in("id",ids));

        return companies.stream().map(obj ->{
            CompanyInfoVO v = new CompanyInfoVO();
            BeanUtils.copyProperties(obj,v);
            v.setCompanyId(obj.getId());
            return v;
        }).collect(Collectors.toList());
    }

    @Override
    public void updateAggsUserInfo(ReviewCompanyBO bo) {

        String companyId = bo.getCompanyId();
        String hrUserId = bo.getHrUserId();
        Company company = companyMapper.selectById(companyId);
        if(company != null){
            String companyName = company.getCompanyName();

            BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
            queryBuilder.must(QueryBuilders.termQuery("userId",hrUserId));
            Query query = new NativeSearchQueryBuilder().withQuery(queryBuilder).build();

            SearchHits<AggsUserEO> search = esTemplate.search(query, AggsUserEO.class);

            //更新hr
            for (SearchHit<AggsUserEO> hit:search){
                  AggsUserEO content = hit.getContent();
                  content.setType(AggsUserType.HR.type);
                  content.setCompanyName(companyName);
                  content.setCompanyId(companyId);
                  esTemplate.save(content);
            }


            //新建一個company對象
            AggsUserEO companyEo = new AggsUserEO();
            companyEo.setCompanyId(companyId);
            companyEo.setCompanyName(companyName);
            companyEo.setType(AggsUserType.COMPANY.type);
            companyEo.setCreateDate(LocalDateUtils.format(LocalDateTime.now(),LocalDateUtils.DATE_PATTERN));
            esTemplate.save(companyEo);
        }


    }

}
